package fastdfs1

import (
	"fmt"
	"github.com/astaxie/beego/httplib"
	"os"
	"runtime"
	"strconv"
	"sync"
	"time"
)

type UploadParams struct {
	Fs string  //go-fastdns 上传地址
	fileMapAll []map[string]string  //定义全局变量返回数据
	FileArr []string //传入的数组参数
	errorNum int
	successNum int
}

func (u *UploadParams)UploadAll() []map[string]string {
	runtime.GOMAXPROCS(8)
	FileArr := u.FileArr
	var wg = sync.WaitGroup{}
	//var l = sync.Mutex{}
	num := len(FileArr)
	for i := 0; i < num; i++ {
		wg.Add(1)
		time.Sleep(time.Duration(1)*80*time.Millisecond)
		go u.upload(FileArr[i],i, wg.Done) //子协程上传文件
	}

	wg.Wait() //等待子协程执行完毕
	fmt.Println("文件上传成功数为:" + strconv.Itoa(u.successNum) + "！")
	return u.fileMapAll
}

/**
go-fastdns文件上传
src 文件路径
DeferFunc 协程函数 wg.Done 进行数量减1
*/
func (u *UploadParams)upload(src string,i int, DeferFunc func()) {
	defer func() {
		DeferFunc()
	}()
	var obj interface{}
	req := httplib.Post(u.Fs)
	req.PostFile("file", src) //文件路径
	req.Param("output", "json")
	req.Param("scene", "")
	req.Param("path", "")
	req.ToJSON(&obj)
	if obj == nil {
		u.errorNum++ //上传失败，进行错误计数
		if u.errorNum >= 10 {
			fmt.Println("文件上传失败数为:" + strconv.Itoa(u.errorNum) + "，停止上传！")
			os.Exit(1)
		}else{
			fmt.Println(i,src)
			u.FileArr = append(u.FileArr,src)
			runtime.Goexit() //协程终止
			fmt.Println(222)
		}
	}
	u.successNum++
	fmt.Println(i,u.successNum)
	res := obj.(map[string]interface{})
	res2 := mapInterfaceToMapString(res)
	fileMap := make(map[string]string)
	for key, value := range res2 {
		switch key {
		case "domain":
			fileMap["domain"] = value
		case "md5":
			fileMap["md5"] = value
		case "mtime":
			fileMap["mtime"] = value
		case "path":
			fileMap["path"] = value
		case "scene":
			fileMap["scene"] = value
		case "size":
			fileMap["size"] = value
		case "url":
			fileMap["url"] = value
		}
	}
	u.fileMapAll = append(u.fileMapAll, fileMap) //子协程处理的结果合并到全局变量中
}

// map[string]interface{} 转换成map[string]string
func mapInterfaceToMapString(m map[string]interface{}) map[string]string {
	ret := make(map[string]string, len(m))
	for k, v := range m {
		ret[k] = fmt.Sprint(v)
	}
	return ret
}
